package com.acme.bankapp;

import java.util.Date;

import com.acme.bankapp.domain.bank.*;
import com.acme.bankapp.exceptions.*;
import com.acme.bankapp.service.bank.*;


/**
 * This class tests BankService, Bank and other classes
 * 
 * @author Anton Kotov
 * 
 */
public class BankApplication {

    public static void main(String[] args) {
	boolean bankLoaded = false;
	Bank bank = null;

	try {
	    if ((args.length > 0 && args[0].equals("-loadbank"))
		    || (args.length > 1 && args[1].equals("-loadbank"))) {
		bank = BankService.loadBank("bank.des");
		bankLoaded = true;
	    }

	    if (!bankLoaded) {
		bank = createInMemoryBank();
	    }

	    if ((args.length > 0 && args[0].equals("-loadfeed"))
		    || (args.length > 1 && args[1].equals("-loadfeed"))) {
		BankDataLoaderService.load(bank, "bank.dat");
	    }

	    BankService.saveBank("bank.ser", bank);
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    private static Bank createInMemoryBank() {
	@SuppressWarnings("serial")
	Bank bank = new Bank(new ClientRegistrationListener() {

	    @Override
	    public void onClientAdded(Client client) {
		System.out.println(client.getClientSalutation());
	    }
	}, new ClientRegistrationListener() {

	    @Override
	    public void onClientAdded(Client client) {
		System.out.format(
			"Notification email for client '%s' to be sent%n",
			client.getClientSalutation());
	    }
	}, new ClientRegistrationListener() {

	    @Override
	    public void onClientAdded(Client client) {
		System.out.println(client.getClientSalutation() + " "
			+ new Date());
	    }
	});

	try {
	    BankService.addClients(bank, BankService.addAccounts(new Client(
		    "Bond", Gender.MALE), new CheckingAccount(0, 0.0, 1.0)),
		    BankService.addAccounts(new Client("Smith", Gender.FEMALE),
			    new SavingAccount(1, 0.0)), BankService
			    .addAccounts(new Client("Hood", Gender.MALE),
				    new CheckingAccount(2, 0.0, 1.0)),
		    BankService.addAccounts(new Client("John", Gender.FEMALE),
			    new SavingAccount(3, 0.0)), BankService
			    .addAccounts(new Client("Marion", Gender.MALE),
				    new CheckingAccount(4, 0.0, 1.0)),
		    BankService.addAccounts(new Client("Dale", Gender.FEMALE),
			    new SavingAccount(5, 0.0)), BankService
			    .addAccounts(new Client("Tuck", Gender.MALE),
				    new CheckingAccount(6, 0.0, 1.0)),
		    BankService.addAccounts(
			    new Client("Scarlet", Gender.FEMALE),
			    new SavingAccount(7, 0.0)), BankService
			    .addAccounts(new Client("Grant", Gender.MALE),
				    new CheckingAccount(8, 0.0, 1.0)),
		    BankService.addAccounts(new Client("Brown", Gender.FEMALE),
			    new SavingAccount(9, 0.0)));
	    BankService.addClients(bank, BankService.addAccounts(new Client(
		    "Bond", Gender.FEMALE), new SavingAccount(10, 0.0)));
	} catch (ClientExistsException e) {
	    System.out.println(e);
	}

	BankService.printBalance(bank);
	BankService.printMaximumAmountToWithdraw(bank);

	try {
	    BankService.modifyBank(bank);
	} catch (OverDraftLimitExceededException e) {
	    StringBuilder message = new StringBuilder();
	    message.append(e.getMessage());
	    for (Throwable t = e; (t = t.getCause()) != null;) {
		message.append("\n\tCause is: ");
		message.append(t.getMessage());
	    }
	    System.out.println(message);
	} catch (NotEnoughFundsException e) {
	    System.out.println(e.getMessage());
	}

	BankService.printBalance(bank);
	BankService.printMaximumAmountToWithdraw(bank);

	return bank;
    }

}
